package com.android.clinic.doctors.app.glide;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Date;

/**
 * Created by cheng on 2018/6/19.
 */
public class FileUtils {

    //设置文件的超时时间
    public static int CACHE_TIME = 3 * 60 * 1000;
    public static final String SDPATH = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "ooo";
//    public static final String DATAPATH = Environment.getDataDirectory().getAbsolutePath() + File.separator + "ooo";

    /*
 * 字符串保存到本地
 * 返回值：字符串写入本地是否成功
 * 思路：若文件存在，则删除；然后创建一个新的文件，并把数据写入文件
 * */
    public static boolean write2File(Context context, String str, String fileName) {
        boolean result = false;
        try {
            if (TextUtils.isEmpty(fileName)) {
                return result;
            }
            deleteFile(fileName);
            createDir();

            File file = new File(SDPATH, fileName);
            file.createNewFile();

            FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
            fos.write(str.getBytes());
            fos.close();
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
            result = false;
        }
        return result;
    }

    /*
     * 字符串以流的形式保存到本地
     * 返回值：字符串写入本地是否成功
     * 思路：若文件存在，则删除；然后创建一个新的文件，并把数据写入文件
     * */
    public static void write2File(Context context, InputStream in, String fileName) {
        try {
            deleteFile(fileName);
            createDir();
            File file = new File(SDPATH, fileName);
            file.createNewFile();

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] bytes = new byte[1024 * 4];
            int n = 0;
            while ((n = in.read(bytes)) != -1) {
                bos.write(bytes, 0, n);
            }
            FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
            fos.write(bos.toByteArray());
            fos.close();
            bos.close();
            in.close();
            bytes = null;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
    * 从本地获取文件字符串
    * boolean cacheTime:缓存时间是否有效。true(有效)，文件存储时
    * 间超时，则不取;false(无效),不论文件是否超时，都取。
    * */
    public static String read2File(Context context, String fileName, boolean cacheTime) {
        String result = "";
        try {
            if (context == null || TextUtils.isEmpty(fileName)) {
                return result;
            }
            File file = new File(SDPATH, fileName);
            if (!file.exists()) {
                return result;
            } else if (cacheTime && System.currentTimeMillis() - file.lastModified() > CACHE_TIME) {
                return result;
            }
            FileInputStream fis = context.openFileInput(fileName);
            byte[] bytes = new byte[fis.available()];
            fis.read(bytes);
            result = new String(bytes);
            fis.close();
            bytes = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    //通过文件名删除文件
    public static boolean deleteFile(String fileName) {
        boolean ret = false;
        File file = new File(SDPATH, fileName);
        if (file.exists()) {
            file.delete();
            ret = true;
        }
        return ret;
    }

    //把图片存入本地
    public static boolean writeBitmap2File(Bitmap bitmap, String fileName) {
        boolean result = false;
        try {
            deleteFile(fileName);
            createDir();
            File file = new File(SDPATH, fileName);
            file.createNewFile();

            FileOutputStream fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
            fos.flush();
            fos.close();
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
            result = false;
        }
        return result;
    }

    //从本地获取图片
    public static Bitmap readBitmap2Cache(Context context, String fileName, boolean cacheTime) {
        Bitmap bitmap = null;
        try {
            File file = new File(SDPATH, fileName);//context.getFilesDir()
            if (!file.exists()) {
                return bitmap;
            } else if (cacheTime && System.currentTimeMillis() - file.lastModified() > CACHE_TIME) {
                return bitmap;
            }
            FileInputStream fis = context.openFileInput(fileName);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inPreferredConfig = Bitmap.Config.ARGB_8888;
            bitmap = BitmapFactory.decodeStream(fis, null, options);
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    //根据id获取图片
    public static Bitmap readBitMap(Context context, int resId) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        // 获取资源图片
        InputStream is = context.getResources().openRawResource(resId);
        return BitmapFactory.decodeStream(is, null, options);
    }

    private static void createDir() {
        File f = new File(SDPATH);
        if (!f.exists()) {
            f.mkdir();
        }
    }

    /**
     * 图片存入相册
     */
    public static void write2album(Context context, Bitmap bitmap) {
        String path = MediaStore.Images.Media.insertImage(context.getContentResolver(), bitmap, "", "");
        //发送通知刷新图库
        //4.4以后限制了系统应用才有权限使用广播通知系统扫描SD卡
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Intent mediaScanIntent = new Intent(
                    Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            mediaScanIntent.setData(Uri.parse(path));
            context.sendBroadcast(mediaScanIntent);
        } else {
            context.sendBroadcast(new Intent(
                    Intent.ACTION_MEDIA_MOUNTED,
                    Uri.parse("file://"
                            + Environment.getExternalStorageDirectory())));
        }
    }

    /**
     * 文件复制
     */
    public static long copyFile(File f1, File f2) throws Exception {
        long time = new Date().getTime();
        int length = 2097152;
        FileInputStream in = new FileInputStream(f1);
        FileOutputStream out = new FileOutputStream(f2);
        byte[] buffer = new byte[length];
        while (true) {
            int ins = in.read(buffer);
            if (ins == -1) {
                in.close();
                out.flush();
                out.close();
                return new Date().getTime() - time;
            } else
                out.write(buffer, 0, ins);
        }
    }

    private static long getFolderSize(File file) {
        long size = 0;
        try {
            File[] fileList = file.listFiles();
            for (File aFileList : fileList) {
                if (aFileList.isDirectory()) {
                    size = size + getFolderSize(aFileList);
                } else {
                    size = size + aFileList.length();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return size;
    }

    /**
     * 获取指定文件夹内所有文件大小的和
     */
    public static String getFormatSize(File file) {
        long size = getFolderSize(file);
        double kiloByte = size / 1024;
        if (kiloByte < 1) {
            return size + "B"; //Byte
        }
        double megaByte = kiloByte / 1024;
        if (megaByte < 1) {
            BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
            return result1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "KB";
        }
        double gigaByte = megaByte / 1024;
        if (gigaByte < 1) {
            BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
            return result2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "MB";
        }
        double teraBytes = gigaByte / 1024;
        if (teraBytes < 1) {
            BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
            return result3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "GB";
        }
        BigDecimal result4 = new BigDecimal(teraBytes);
        return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "TB";
    }

}
